
/**************************************************************
 * 
 * Copyright ? 2012，北京福富软件技术股份有限公司
 * All Rights Reserved.
 * ------------------------------------------------------------
 * 文件名称：StringUtil.java
 * 文件摘要：字符串工具包
 * 初始版本：V1.0.0
 * 初始作者：Linz
 * 完成日期：2012-02
 * 
 **************************************************************/
package com.util;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.security.MessageDigest;
import java.text.DecimalFormat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**************************************************************************
 * 
 * 类名：StringUtil<br>
 * <br>
 * 功能：字符串工具包<br>
 * <br>
 * 作者：Linz 2012-02<br>
 * <br>
 * 属性列表：<br>
 * 		无<br>
 * <br>
 * 方法列表：<br>
 * 		public static String NVL(Object inObj)<br>
 * 		public static String toGBK(String inStr)<br>
 * 		public static String toGBK(String inStr, boolean isGBK)<br>
 * 		public static String toISO(String inStr)<br>
 * 		public static String toISO(String inStr, boolean isGBK)<br>
 * 		public static long ipStringToLong(String ipStr)<br>
 * 		public static String longToIpString(long ipLong)<br>
 * 		public static boolean isIpString(String ipStr)<br>
 * 		public static String getMd5Encrypt(String value)<br>
 * 		public static String reverseString(String inStr)<br>
 * 		...<br>
 * <br>
 * 修改记录：<br>
 * 		日期				修改人			修改说明<br>
 * 
 **************************************************************************/
public class StringUtil 
{
	/**************************************************************************
	 * 
	 * 函数名：public static String NVL(Object inObj)<br>
	 * <br>
	 * 功能：把Object转为字符串格式，如果为null，转为""<br>
	 * <br>
	 * 作者：Linz 2012-02<br>
	 * <br>
	 * 参数表：<br>
	 * 		Object inObj -> 对象<br>
	 * <br>
	 * 返回值：<br>
	 * 		String -> 字符串格式<br>
	 * <br>
	 * 修改记录：<br>
	 * 		日期				修改人			修改说明<br>
	 * 
	 **************************************************************************/
	public static String NVL(Object inObj) 
	{
		return inObj==null ? "" : inObj.toString();
	}
	
	
	/**************************************************************************
	 * 
	 * 函数名：public static String toGBK(String inStr)<br>
	 * <br>
	 * 功能：把字符串转换成GBK内码<br>
	 * <br>
	 * 作者：Linz 2012-02<br>
	 * <br>
	 * 参数表：<br>
	 * 		String inStr -> 需要转换的String<br>
	 * <br>
	 * 返回值：<br>
	 * 		String -> 转换内码的String<br>
	 * <br>
	 * 修改记录：<br>
	 * 		日期				修改人			修改说明<br>
	 * 
	 **************************************************************************/
	public static String toGBK(String inStr)
	{
		if (inStr==null) { return null; }
		try 
		{
			return new String(inStr.getBytes("ISO_8859_1"), "GBK");
		}
		catch (Exception e) 
		{
			return null;
		}
	}
	
	
	/**************************************************************************
	 * 
	 * 函数名：public static String toGBK(String inStr, boolean isGBK)<br>
	 * <br>
	 * 功能：根据是否中文标志，把字符串转换成GBK内码<br>
	 *      如isGBK=true，不转换，主要用于出库显示<br>
	 * <br>
	 * 作者：Linz 2012-02<br>
	 * <br>
	 * 参数表：<br>
	 * 		String  inStr -> 需要转换的String<br>
	 * 		boolean isGBK -> 是否中文标志<br>
	 * <br>
	 * 返回值：<br>
	 * 		String -> 转换内码的String<br>
	 * <br>
	 * 修改记录：<br>
	 * 		日期				修改人			修改说明<br>
	 * 
	 **************************************************************************/
	public static String toGBK(String inStr, boolean isGBK)
	{
		return isGBK ? inStr : toGBK(inStr);
	}
	
	
	/**************************************************************************
	 * 
	 * 函数名：public static String toISO(String inStr)<br>
	 * <br>
	 * 功能：把字符串转换成ISO内码<br>
	 * <br>
	 * 作者：Linz 2012-02<br>
	 * <br>
	 * 参数表：<br>
	 * 		String inStr -> 需要转换的String<br>
	 * <br>
	 * 返回值：<br>
	 * 		String -> 转换内码的String<br>
	 * <br>
	 * 修改记录：<br>
	 * 		日期				修改人			修改说明<br>
	 * 
	 **************************************************************************/
	public static String toISO(String inStr)
	{
		if (inStr==null) { return null; }
		try 
		{
			return new String(inStr.getBytes("GBK"), "ISO_8859_1");
		}
		catch (Exception e) 
		{
			return null;
		}
	}
	
	
	/**************************************************************************
	 * 
	 * 函数名：public static String toISO(String inStr, boolean isGBK)<br>
	 * <br>
	 * 功能：根据是否中文标志，把字符串转换成GBK内码<br>
	 *      如isGBK=true，不转换，主要用于入库<br>
	 * <br>
	 * 作者：Linz 2012-02<br>
	 * <br>
	 * 参数表：<br>
	 * 		String  inStr -> 需要转换的String<br>
	 * 		boolean isGBK -> 是否中文标志<br>
	 * <br>
	 * 返回值：<br>
	 * 		String -> 转换内码的String<br>
	 * <br>
	 * 修改记录：<br>
	 * 		日期				修改人			修改说明<br>
	 * 
	 **************************************************************************/
	public static String toISO(String inStr, boolean isGBK)
	{
		return isGBK ? inStr : toISO(inStr);
	}
	
	
	/**************************************************************************
	 * 
	 * 函数名：public static long ipStringToLong(String ipStr)<br>
	 * <br>
	 * 功能：把ip地址串转换成长整形数<br>
	 * <br>
	 * 作者：Linz 2012-02<br>
	 * <br>
	 * 参数表：<br>
	 * 		String ipStr -> 需要转换的ip地址<br>
	 * <br>
	 * 返回值：<br>
	 * 		long -> 转换后的长整形ip<br>
	 * <br>
	 * 修改记录：<br>
	 * 		日期				修改人			修改说明<br>
	 * 
	 **************************************************************************/
	public static long ipStringToLong(String ipStr)
	{
		if (ipStr==null || "".equals(ipStr)) { return -999999; }
		try 
		{
			String[] ipArray = ipStr.split("\\.");
			if (ipArray.length != 4) { return -999999; }
			for (int i=0; i<ipArray.length; i++)
			{
				if (ipArray[i].length()>3 || Long.parseLong(ipArray[i])<0 || Long.parseLong(ipArray[i])>255) 
				{
					return -999999;
				}
			}
			long lg1 = Long.parseLong(ipArray[0])*256*256*256;
			long lg2 = Long.parseLong(ipArray[1])*256*256;
			long lg3 = Long.parseLong(ipArray[2])*256;
			long lg4 = Long.parseLong(ipArray[3]);
			return lg1 + lg2 + lg3 + lg4;
		}
		catch (Exception e) 
		{
			return -999999;
		}
	}
	
	
	/**************************************************************************
	 * 
	 * 函数名：public static String longToIpString(long ipLong) <br>
	 * <br>
	 * 功能：把长整形ip转为字符串地址<br>
	 * <br>
	 * 作者：Linz 2012-02<br>
	 * <br>
	 * 参数表：<br>
	 * 		long ipLong -> 需要转换的ip地址<br>
	 * <br>
	 * 返回值：<br>
	 * 		String -> 转换后的字符串ip<br>
	 * <br>
	 * 修改记录：<br>
	 * 		日期				修改人			修改说明<br>
	 * 
	 **************************************************************************/
	public static String longToIpString(long ipLong) 
	{
		if (ipLong==0) { return "0.0.0.0"; }
		if (ipLong<0)  { return null; }
		try 
		{
			long ip1 = ipLong / (256*256*256);
			long ip2 = (ipLong-ip1*256*256*256) / (256*256);
			long ip3 = (ipLong-ip1*256*256*256-ip2*256*256) / 256;
			long ip4 = ipLong % 256;
			return "" + ip1 + "." + ip2 + "." + ip3 + "." + ip4;
		}
		catch (Exception e) 
		{
			return null;
		}
	}
	
	
	/**************************************************************************
	 * 
	 * 函数名：public static boolean isIpString(String ipStr)<br>
	 * <br>
	 * 功能：判断传入的字符串是否是正确的IP地址<br>
	 * <br>
	 * 作者：Linz 2012-02<br>
	 * <br>
	 * 参数表：<br>
	 * 		String ipStr -> 传入的字符串<br>
	 * <br>
	 * 返回值：<br>
	 * 		boolean -> 是否为IP, true->是, false->否<br>
	 * <br>
	 * 修改记录：<br>
	 * 		日期				修改人			修改说明<br>
	 * 
	 **************************************************************************/
	public static boolean isIpString(String ipStr)
	{
		if (ipStr==null || "".equals(ipStr)) { return false; }
		String regex = "(((2[0-4]\\d)|(25[0-5]))|(1\\d{2})|([0-9]\\d)|(\\d))"
			+ "[.]"
			+ "(((2[0-4]\\d)|(25[0-5]))|(1\\d{2})|([0-9]\\d)|(\\d))"
			+ "[.]"
			+ "(((2[0-4]\\d)|(25[0-5]))|(1\\d{2})|([0-9]\\d)|(\\d))"
			+ "[.]"
			+ "(((2[0-4]\\d)|(25[0-5]))|(1\\d{2})|([0-9]\\d)|(\\d))";
		Pattern   p  = Pattern.compile(regex);
		Matcher   m  = p.matcher(ipStr);
		return m.matches();
	}
	
	
	/**************************************************************************
	 * 
	 * 函数名：public static String getMd5Encrypt(String value)<br>
	 * <br>
	 * 功能：将给定的字符串转为MD5的加密字符串<br>
	 * <br>
	 * 作者：Linz 2012-02<br>
	 * <br>
	 * 参数表：<br>
	 * 		String value -> 加密前的字符串<br>
	 * <br>
	 * 返回值：<br>
	 * 		String -> 加密后的字符串<br>
	 * <br>
	 * 修改记录：<br>
	 * 		日期				修改人			修改说明<br>
	 * 
	 **************************************************************************/
	public static String getMd5Encrypt(String value)
	{
		if (value==null) { return null; }
		//定义十六进制序列
		String hexSequence = "0123456789abcdef";
		
		//将参数的字符串转为字节数组
		byte[] preparedMessage = value.getBytes();
		
		//生成实现MD5摘要算法的 MessageDigest 对象
		MessageDigest md = null;
		
		try 
		{
			md = MessageDigest.getInstance("MD5");
		}
		catch (Exception e) 
		{
			e.printStackTrace();
		}
		
		//使用指定的字节串更新此摘要
		md.update(preparedMessage);
		
		//完成哈希算法
		byte[] newMessage = md.digest();
		
		//返回
		int length = newMessage.length;
		char[] message = new char[length*2];
		int index = 0;
		for (int i=0; i<length; i++)
		{
			message[index++] = hexSequence.charAt(newMessage[i]>>>4 & 0xf);
			message[index++] = hexSequence.charAt(newMessage[i] & 0xf);
		}
		return new String(message);
	}
	
	
	/**************************************************************************
	 * 
	 * 函数名：public static String reverseString(String inStr)<br>
	 * <br>
	 * 功能：字符串反转<br>
	 * <br>
	 * 作者：Linz 2012-02<br>
	 * <br>
	 * 参数表：<br>
	 * 		String inStr -> 传入的字符串<br>
	 * <br>
	 * 返回值：<br>
	 * 		String -> 反转后的字符串<br>
	 * <br>
	 * 修改记录：<br>
	 * 		日期				修改人			修改说明<br>
	 * 
	 **************************************************************************/
	public static String reverseString(String inStr) 
	{
		byte[]  bt = inStr.getBytes();
		int length = bt.length;
		int half   = bt.length/2;
		byte temp  = 0;
		for (int i=0; i<half; i++) {
			temp   = bt[i];
			bt[i]  = bt[length-1-i];
			bt[length-1-i] = temp;
		}
		return new String(bt);
	}
	/**************************************************************************
	 * 
	 * 函数名：public String longToFlowString(long fl)<br>
	 * <br>
	 * 功能：将流量的整形数转为字符串<br>
	 * <br>
	 * 作者：Linz 2010-09-09<br>
	 * <br>
	 * 参数表：<br>
	 * 		long fl -> 流量值(字节)<br>
	 * <br>
	 * 返回值：<br>
	 * 		String -> 转换后的字符串<br>
	 * <br>
	 * 修改记录：<br>
	 * 		日期				修改人			修改说明<br>
	 * 		2010-09-16		Linz			流量(Byte)转化为后保留小数点后2位<br>
	 * 
	 **************************************************************************/
	public static String longToFlowString(long fl)
	{
		if (fl<1024)
		{
			return fl + " Byte";
		}
		if (fl<1024*1024)
		{
			return new DecimalFormat("#.##").format(fl*1.0/1024)+" KB";
		}
		if (fl<1024*1024*1024)
		{
			return new DecimalFormat("#.##").format(fl*1.0/(1024*1024))+" MB";
		}
		else
		{
			return new DecimalFormat("#.##").format(fl*1.0/(1024*1024*1024))+" GB";
		}
	}	
	/**
	 * 
	 * 作者： ZhengYan <br />
	 * 
	 * 方法名：GetObjectDebugFormatString	 <br />
	 * 功能：获取对象调试信息格式化描述字符串 <br />
	 * 参数列表： <br />
	 * 		@param obj 要描述的对象
	 * 		@return 调试信息格式化描述字符串 <br />
	 * 日期：2013-3-14 <br />
	 */
	@SuppressWarnings({ "unchecked", "rawtypes", "unused" })
	public static String GetObjectDebugFormatString(Object obj)
	{
		Class c = obj.getClass();
		StringBuffer result = new StringBuffer();
		//取得包括private在内的列
		Field[] fields = c.getDeclaredFields();
		Field field = null;
		Method method = null;
		String colName = "";
		result.append("\n{");
		for (int i = 0; i < fields.length; i++) {
			try{
				colName = fields[i].getName();
				method = c.getMethod("get"+colName.substring(0, 1).toUpperCase() + colName.substring(1));
				Object object = method.invoke(obj);
				result.append("  "+colName+"="+object+"  ");
				if(i!=fields.length-1)
					result.append(",");
			}catch(Exception e){
				System.out.println("列"+colName+"反射异常!");
				e.printStackTrace();
			}
		}
		result.append("}");
		return result.toString();
	} 
}
